package com.example.demo.synchronizer;

import com.example.demo.entity.CopyrightEntity;
import com.example.demo.entity.CopyrightTransferEntity;
import com.example.demo.model.CopyrightInfo;
import com.example.demo.repository.CopyrightRepository;
import com.example.demo.repository.CopyrightTransferRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import java.math.BigInteger;
import java.util.Date;
import java.util.Optional;

/**
 * 版权数据同步器，处理区块链与数据库的数据同步
 */
@Slf4j
@Component
public class CopyrightDataSynchronizer {
    
    @Autowired
    private CopyrightRepository copyrightRepository;
    
    @Autowired
    private CopyrightTransferRepository transferRepository;
    
    /**
     * 同步版权创建信息到数据库
     * @param copyrightId 版权ID
     * @param imageHash 图片哈希
     * @param ownerAddress 所有者地址
     * @param txHash 交易哈希
     * @return 同步后的版权实体
     */
    public CopyrightEntity syncCopyrightCreation(BigInteger copyrightId, String imageHash, 
                                               String ownerAddress, String txHash) {
        log.info("同步版权创建信息到数据库: ID={}, 哈希={}, 所有者={}, 交易哈希={}", 
            copyrightId, imageHash, ownerAddress, txHash);
            
        try {
            // 尝试查找现有记录
            CopyrightEntity entity = copyrightRepository.findByBlockchainId(copyrightId.toString())
                    .orElse(null);
                    
            if (entity != null) {
                // 更新现有记录
                entity.setTxHash(txHash);
                
                // 设置区块链时间，转换为秒
                long currentTime = System.currentTimeMillis() / 1000;
                entity.setBlockchainTime(currentTime);
                
                copyrightRepository.save(entity);
                log.info("更新版权记录成功，添加交易哈希");
            } else {
                // 创建新记录
                entity = new CopyrightEntity();
                entity.setBlockchainId(copyrightId.toString());
                entity.setImageHash(imageHash);
                entity.setOwnerAddress(ownerAddress);
                entity.setCreateTime(new Date());
                entity.setIsValid(true);
                entity.setTxHash(txHash);
                
                // 设置区块链时间 转换为秒
                long currentTime = System.currentTimeMillis() / 1000;
                entity.setBlockchainTime(currentTime);
                
                copyrightRepository.save(entity);
                log.info("创建版权记录成功，包含交易哈希");
            }
            
            return entity;
        } catch (Exception e) {
            log.error("同步版权创建信息异常: {}", e.getMessage(), e);
            throw new RuntimeException("同步版权创建信息失败: " + e.getMessage(), e);
        }
    }
    
    /**
     * 同步版权元数据到数据库
     * @param copyrightId 版权ID
     * @param imagePath 图片路径
     * @param imageName 图片名称
     * @param imageSize 图片大小
     * @param modelName 模型名称
     * @param prompt 提示词
     * @return 同步后的版权实体
     */
    public CopyrightEntity syncCopyrightMetadata(BigInteger copyrightId, String imagePath, 
                                               String imageName, Long imageSize, 
                                               String modelName, String prompt) {
        log.info("同步版权元数据到数据库: ID={}, 图片名称={}", copyrightId, imageName);
        
        try {
            // 查找版权记录
            Optional<CopyrightEntity> optionalEntity = copyrightRepository.findByBlockchainId(copyrightId.toString());
            
            if (optionalEntity.isPresent()) {
                CopyrightEntity entity = optionalEntity.get();
                
                // 更新元数据
                entity.setImagePath(imagePath);
                entity.setImageName(imageName);
                entity.setImageSize(imageSize);
                entity.setModelName(modelName);
                entity.setPrompt(prompt);
                
                // 保存更新
                copyrightRepository.save(entity);
                log.info("更新版权元数据成功: ID={}", copyrightId);
                
                return entity;
            } else {
                log.warn("未找到版权记录，无法更新元数据: ID={}", copyrightId);
                return null;
            }
        } catch (Exception e) {
            log.error("同步版权元数据异常: {}", e.getMessage(), e);
            throw new RuntimeException("同步版权元数据失败: " + e.getMessage(), e);
        }
    }
    
    /**
     * 同步链上所有权变更到数据库
     * @param copyrightId 版权ID
     * @param newOwner 新所有者
     */
    public void syncOwnershipChange(BigInteger copyrightId, String newOwner) {
        log.info("同步链上所有权变更到数据库: ID={}, 新所有者={}", copyrightId, newOwner);
        
        try {
            // 查找版权记录
            CopyrightEntity entity = copyrightRepository.findByBlockchainId(copyrightId.toString())
                    .orElse(null);
                    
            if (entity != null) {
                // 记录旧所有者
                String oldOwner = entity.getOwnerAddress();
                
                // 如果所有者已经是新所有者，不需要更新
                if (oldOwner.equalsIgnoreCase(newOwner)) {
                    log.info("所有者未变化，无需更新: ID={}, 所有者={}", copyrightId, newOwner);
                    return;
                }
                
                // 更新所有者
                entity.setOwnerAddress(newOwner);
                copyrightRepository.save(entity);
                
                log.info("更新所有权成功: ID={}, 从{}到{}", copyrightId, oldOwner, newOwner);
            } else {
                log.warn("未找到版权记录，无法更新所有权: ID={}", copyrightId);
            }
        } catch (Exception e) {
            log.error("同步所有权变更异常: {}", e.getMessage(), e);
            throw new RuntimeException("同步所有权变更失败: " + e.getMessage(), e);
        }
    }
    
    /**
     * 记录版权转让历史
     * @param copyrightId 版权ID（数据库ID）
     * @param fromAddress 转让方地址
     * @param toAddress 接收方地址
     * @param txHash 交易哈希
     * @return 创建的转让记录
     */
    public CopyrightTransferEntity recordTransferHistory(Long copyrightId, String fromAddress, 
                                                       String toAddress, String txHash) {
        log.info("记录版权转让历史: 版权ID={}, 从{}到{}, 交易哈希={}", 
            copyrightId, fromAddress, toAddress, txHash);
            
        try {
            // 创建转让记录
            CopyrightTransferEntity transfer = new CopyrightTransferEntity();
            transfer.setCopyrightId(copyrightId);
            transfer.setFromAddress(fromAddress);
            transfer.setToAddress(toAddress);
            transfer.setTransferTime(new Date());
            transfer.setTxHash(txHash);
            // 1-成功
            transfer.setStatus(1);
            transfer.setRemarks("版权转让交易");
            
            // 保存记录
            transfer = transferRepository.save(transfer);
            log.info("保存转让记录成功: ID={}", transfer.getId());
            
            return transfer;
        } catch (Exception e) {
            log.error("记录版权转让历史异常: {}", e.getMessage(), e);
            throw new RuntimeException("记录版权转让历史失败: " + e.getMessage(), e);
        }
    }
    
    /**
     * 根据区块链ID查找数据库ID
     * @param blockchainId 区块链ID
     * @return 数据库ID，如果不存在则返回null
     */
    public Long findDatabaseIdByBlockchainId(String blockchainId) {
        try {
            Optional<CopyrightEntity> entityOpt = copyrightRepository.findByBlockchainId(blockchainId);
            return entityOpt.map(CopyrightEntity::getId).orElse(null);
        } catch (Exception e) {
            log.error("查找数据库ID异常: {}", e.getMessage(), e);
            return null;
        }
    }
    
    /**
     * 从数据库获取版权信息
     * @param copyrightId 版权ID（区块链ID）
     * @return 版权信息
     */
    public CopyrightInfo getCopyrightFromDB(BigInteger copyrightId) {
        log.info("从数据库获取版权信息: ID={}", copyrightId);
        
        try {
            // 从数据库中查询指定ID的版权
            CopyrightEntity entity = copyrightRepository.findByBlockchainId(copyrightId.toString())
                    .orElse(null);
            
            if (entity == null) {
                log.warn("数据库中未找到版权: ID={}", copyrightId);
                return null;
            }
            
            // 转换为版权信息对象
            CopyrightInfo info = new CopyrightInfo();
            info.setId(entity.getId());
            info.setBlockchainId(entity.getBlockchainId());
            info.setImageHash(entity.getImageHash());
            info.setOwnerAddress(entity.getOwnerAddress());
            
            // 处理日期转换
            if (entity.getCreateTime() != null) {
                info.setCreateTime(BigInteger.valueOf(entity.getCreateTime().getTime() / 1000));
            }
            
            info.setIsValid(entity.getIsValid());
            info.setTxHash(entity.getTxHash());
            info.setBlockchainTime(entity.getBlockchainTime());
            info.setImagePath(entity.getImagePath());
            info.setImageName(entity.getImageName());
            info.setImageSize(entity.getImageSize());
            info.setModelName(entity.getModelName());
            info.setPrompt(entity.getPrompt());
            
            log.info("从数据库获取版权成功: ID={}, 所有者={}", copyrightId, info.getOwnerAddress());
            return info;
        } catch (Exception e) {
            log.error("从数据库获取版权信息异常: {}", e.getMessage(), e);
            return null;
        }
    }
    
    /**
     * 异步执行全量数据同步
     */
    @Async
    public void synchronizeAllData() {
        log.info("开始全量数据同步...");
        try {
            // 这里应该实现全量数据同步的逻辑
            // 例如，从区块链获取所有版权，然后更新数据库
            log.info("全量数据同步完成");
        } catch (Exception e) {
            log.error("全量数据同步异常: {}", e.getMessage(), e);
        }
    }
} 